home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Memphis Amiga Group / MAG Disk 116 (1989-05)(Memphis Amiga Group).zip / MAG Disk 116 (1989-05)(Memphis Amiga Group).adf / loadpic.c < prev    next >
C/C++ Source or Header  |  1986-11-06  |  7KB  |  326 lines

  1. /*
  2.  * loadpic.c - ILBM loader which runs from the workbench
  3.  *
  4.  * Written by Jonathan Hue - if you decide to steal some of this
  5.  * code (yeah, like anyone would want to), give me credit.
  6.  */
  7. #include <exec/types.h>
  8. #include <workbench/startup.h>
  9. #include <intuition/intuition.h>
  10. #include <graphics/gfxmacros.h>
  11. #include <graphics/view.h>
  12. #include <graphics/gfxbase.h>
  13. #include <graphics/gfx.h>
  14. #include <libraries/dosextens.h>
  15. #include <stdio.h>
  16. #include "types.h"
  17. #include "ilbm.h"
  18.  
  19. extern struct WBStartup *WBenchMsg;
  20. void LoadPic(), ChkRead(), ErrExit(), cleanup(), ReadPic();
  21. int WaitForMouseClick();
  22. struct IntuitionBase *IntuitionBase;
  23. struct GfxBase *GfxBase;
  24. extern struct ColorMap *GetColorMap();
  25. extern struct FileLock *Lock(), *CurrentDir();
  26. extern struct Window *OpenWindow();
  27.  
  28. struct View v;
  29. struct ViewPort vp;
  30. struct ColorMap *cm;
  31. struct BitMap b;
  32. BitMapHeader bm;
  33.  
  34. short WinWidth, WinHeight;    /* Trust me, you don't want to know what */
  35. struct Preferences prefs;    /* I want these for...             */
  36.  
  37. main(argc, argv)
  38. int argc;
  39. char **argv;
  40. {
  41.     struct WBArg *arg;
  42.     struct FileLock *lock, *olddir;
  43.     register int i;
  44.  
  45.     if ((GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 0)) ==
  46.            NULL)
  47.     ErrExit("Couldn't open graphics library");
  48.     if ((IntuitionBase = (struct IntuitionBase *)
  49.              OpenLibrary("intuition.library", 0)) == NULL)
  50.     ErrExit("Couldn't open graphics library");
  51.  
  52.     WinWidth = GfxBase->NormalDisplayColumns;
  53.     WinHeight = GfxBase->NormalDisplayRows;
  54.     GetPrefs(&prefs, sizeof(prefs));
  55.     puts("Press Left Mouse Button to Exit");
  56.     fflush(stdout);            /* stdout should be line buffered */
  57.     if (argc > 0)
  58.     {
  59.     while (--argc)
  60.         LoadPic(*++argv);
  61.     }
  62.     else
  63.     {
  64.     for (i = 1, arg = WBenchMsg->sm_ArgList; i < WBenchMsg->sm_NumArgs;
  65.          i++)
  66.     {
  67.         ++arg;
  68.         if (arg->wa_Lock == NULL)
  69.         continue;
  70.         olddir = CurrentDir(arg->wa_Lock);
  71.         if ((lock = Lock(arg->wa_Name, SHARED_LOCK)) == NULL)
  72.         {
  73.         CurrentDir(olddir);
  74.         continue;
  75.         }
  76.         LoadPic(arg->wa_Name);
  77.         UnLock(lock);
  78.         CurrentDir(olddir);
  79.     }
  80.     }
  81.     cleanup();
  82. }
  83.  
  84.  
  85. void
  86. LoadPic(PicName)
  87. char *PicName;
  88. {
  89.     register FILE *fp;
  90.     u_long form, ilbm, id, nbytes, ViewMode = 0;
  91.     register short i;
  92.     register u_short *ColorMapPtr, ColorValue;
  93.     short GotBody = 0, GotHdr = 0, plane;
  94.     struct View *oldview;
  95.     struct RasInfo ri;
  96.     
  97.     if ((fp = fopen(PicName, "r")) == NULL)
  98.     {
  99.     fprintf(stderr, "Couldn't open %s\n", PicName);
  100.         return;
  101.     }
  102.     ChkRead(fp, &form, sizeof(form));
  103.     fseek(fp, 4L, 1);
  104.     ChkRead(fp, &ilbm, sizeof(ilbm));
  105.     if ((form != ID_FORM) || (ilbm != ID_ILBM))
  106.     ErrExit("Sorry, I can't read this file");
  107.     while (1)
  108.     {
  109.     ChkRead(fp, &id, sizeof(id));
  110.     ChkRead(fp, &nbytes, sizeof(nbytes));
  111.     switch(id)
  112.     {
  113.         case ID_BMHD:
  114.         GotHdr++;
  115.         if (nbytes != sizeof(bm))
  116.             ErrExit("Short header length");
  117.         ChkRead(fp, &bm, sizeof(bm));
  118.         break;
  119.         case ID_CMAP:
  120.         cm = GetColorMap(nbytes / 3);
  121.         ColorMapPtr = (u_short *) cm->ColorTable;
  122.         for (i = 0; i < nbytes / 3; i++)
  123.         {
  124.             ColorValue = (getc(fp) >> 4) << 8;
  125.             ColorValue |= (getc(fp) >> 4) << 4;
  126.             ColorValue |= (getc(fp) >> 4);
  127.             *ColorMapPtr++ = ColorValue;
  128.         }
  129.         if (nbytes & 1)
  130.             getc(fp);
  131.         break;
  132.         case ID_CAMG:
  133.         ChkRead(fp, &ViewMode, sizeof(ViewMode));
  134.         break;
  135.         case ID_BODY:
  136.         if (!GotHdr)
  137.             ErrExit("Found BODY before BMHD!!!");
  138.         GotBody = 1;
  139.         break;
  140.         case ID_GRAB:
  141.         case ID_DEST:
  142.         default:
  143.         fseek(fp, nbytes, 1);
  144.         break;
  145.     }
  146.     if (GotBody)
  147.         break;
  148.     }
  149.     oldview = GfxBase->ActiView;
  150.     InitView(&v);
  151.     InitVPort(&vp);
  152.     v.ViewPort = &vp;
  153.     InitBitMap(&b, bm.bm_numplanes, bm.bm_width, bm.bm_height);
  154.     ri.BitMap = &b;
  155.     ri.RxOffset = 0;
  156.     ri.RyOffset = 0;
  157.     vp.DWidth = bm.bm_width;
  158.     vp.DHeight = bm.bm_height;
  159.     vp.RasInfo = &ri;
  160.     vp.ColorMap = cm;
  161.     for (plane = 0; plane < bm.bm_numplanes; plane++)
  162.     if ((b.Planes[plane] = (PLANEPTR) AllocRaster(bm.bm_width,
  163.          bm.bm_height)) == NULL)
  164.         ErrExit("Couldn't allocate enough screen memory");
  165.  
  166.     if (bm.bm_width > 384)            /* should be set */
  167.     ViewMode |= HIRES;
  168.     if (bm.bm_height > 240)
  169.     ViewMode |= LACE;
  170.     if (ViewMode & LACE)
  171.     v.Modes |= LACE;
  172.     vp.Modes = ViewMode;
  173.  
  174.     if (ViewMode & HIRES)            /* center */
  175.     vp.DxOffset = (640 - bm.bm_width) / 2;
  176.     else
  177.     vp.DxOffset = (320 - bm.bm_width) / 2;
  178.     if (ViewMode & LACE)
  179.     vp.DyOffset = ((2 * WinHeight) - bm.bm_height) / 2;
  180.     else
  181.     vp.DyOffset = ((2 * WinHeight) - bm.bm_height) / 2;
  182.  
  183.     MakeVPort(&v, &vp);
  184.     MrgCop(&v);
  185.  
  186.     ReadPic(fp, &bm, &b);
  187.     LoadView(&v);
  188.     WaitForMouseClick();
  189.     LoadView(oldview);
  190.     for (i = 0; i < bm.bm_numplanes; i++)
  191.     {
  192.     FreeRaster(b.Planes[i], bm.bm_width, bm.bm_height);
  193.     b.Planes[i] = NULL;
  194.     }
  195.     FreeColorMap(cm);
  196.     cm = NULL;
  197.     FreeVPortCopLists(&vp);
  198.     FreeCprList(v.LOFCprList);
  199.     FreeCprList(v.SHFCprList);
  200. }
  201.  
  202.  
  203. void
  204. ReadPic(fp, bmhdr, bm)
  205. register FILE *fp;
  206. register BitMapHeader *bmhdr;
  207. register struct BitMap *bm;
  208. {
  209.     register u_char Pixel, *PixelPtr;
  210.     register short plane, row, nbytes, count;
  211.  
  212.     if (bmhdr->bm_compression == 1)
  213.     {
  214.     for (row = 0; row < bmhdr->bm_height; row++)
  215.     {
  216.         for (plane = 0; plane < bmhdr->bm_numplanes; plane++)
  217.         {
  218.         PixelPtr = bm->Planes[plane] + (row * bm->BytesPerRow);
  219.         nbytes = bm->BytesPerRow;
  220.         while (nbytes > 0)
  221.         {
  222.             count = (char) getc(fp);    /* might be negative */
  223.             if (count >= 0)        /* copy n+1 literal */
  224.             {
  225.             count++;
  226.             nbytes -= count;
  227.             while (count--)
  228.                 *PixelPtr++ = getc(fp);
  229.             }
  230.             else if (count >= -127)    /* repeat next -n+1 times */
  231.             {
  232.             count = 1 - count;
  233.             nbytes -= count;
  234.             Pixel = getc(fp);
  235.             while (count--)
  236.                 *PixelPtr++ = Pixel;
  237.             }
  238.         }
  239.         }
  240.     }
  241.     }
  242.     else
  243.     {
  244.     for (row = 0; row < bmhdr->bm_height; row++)
  245.         for (plane = 0; plane < bmhdr->bm_numplanes; plane++)
  246.         ChkRead(fp, bm->Planes[plane] + (row * bm->BytesPerRow),
  247.                 bm->BytesPerRow);
  248.     }
  249. }
  250.  
  251.  
  252. void
  253. ChkRead(fp, buf, nbytes)
  254. FILE *fp;
  255. char *buf;
  256. int nbytes;
  257. {
  258.     if (fread(buf, nbytes, 1, fp) != 1)
  259.     ErrExit("Short read");
  260. }
  261.  
  262.  
  263. void
  264. ErrExit(s)
  265. char *s;
  266. {
  267.     char b[10];
  268.  
  269.     fprintf(stderr, "%s\nPress RETURN", s);
  270.     gets(b);
  271.     cleanup();
  272.     exit(10);
  273. }
  274.  
  275.  
  276. int
  277. WaitForMouseClick()
  278. {
  279.     static struct NewWindow CheeseWhiz = {
  280.     0, 0,            /* position in upper left */
  281.     0, 0,            /* don't init yet */
  282.     -1, -1,            /* default pens */
  283.     MOUSEBUTTONS,
  284.     BORDERLESS | ACTIVATE,
  285.     NULL, NULL, NULL,
  286.     NULL, NULL,
  287.     0, 0, 0, 0,
  288.     WBENCHSCREEN    
  289.     };
  290.     struct IntuiMessage *message;
  291.     struct Window *win;
  292.  
  293.     CheeseWhiz.Width = WinWidth;
  294.     CheeseWhiz.Height = WinHeight;
  295.     if (prefs.LaceWB)
  296.     CheeseWhiz.Height += WinHeight;
  297.     if ((win = OpenWindow(&CheeseWhiz)) == NULL)
  298.     return(-1);
  299.     Wait(1 << win->UserPort->mp_SigBit);
  300.     message = (struct IntuiMessage *) GetMsg(win->UserPort);
  301.     ReplyMsg(message);
  302.     CloseWindow(win);
  303.     return(0);
  304. }
  305.  
  306.  
  307. void
  308. cleanup()
  309. {
  310.     register short i;
  311.  
  312.     if (cm)            /* forget about the other bits */
  313.     FreeColorMap(cm);
  314.     for (i = 0; i < bm.bm_numplanes; i++)
  315.     {
  316.     if (b.Planes[i])
  317.         FreeRaster(b.Planes[i], bm.bm_width, bm.bm_height);
  318.     }
  319.     CloseLibrary(GfxBase);
  320.     CloseLibrary(IntuitionBase);
  321.     fclose(stdin);
  322.     fclose(stdout);
  323.     fclose(stderr);
  324.     rbrk();
  325. }
  326.